<template>
  <div class="uploadImg">
    <span>添加图片</span>
    <input type="file" :name="name" accept="image/*" :capture="isCameraOnly" :key="inputTmpKey"
      @change="handleInputChange">
  </div>
</template>
<script>
  import {
    Icon,
    Tag,
    Toast
  } from 'mand-mobile'
  export default {
    name: 'image-reader',
    components: {
      [Icon.name]: Icon,
      [Tag.name]: Tag,
    },
    props: {
      name: {
        type: String,
        default: 'image-reader'
      },
      quality: {
        type: Number,
        default () {
          return 1 //压缩质量0-1
        }
      },
      isCompress: { //是否压缩
        type: Boolean,
        default: false
      },
      size: {
        type: Number,
        default () {
          return 0 //0为无限制,单位MB
        }
      },
      isCameraOnly: { //是否打开相机
        type: Boolean,
        default: false,
      },
      outputWidth: { //压缩图片输出宽度 不传值默认-1 图片原始宽高，传值为宽高等比缩放
        type: Number,
        default () {
          return -1
        }
      }
    },
    data() {
      return {
        imgFile: {

        },
        compressedDataUrl: null,
        inputTmpKey: Date.now()
      }
    },
    methods: {
      $_cleaeFile() {
        this.inputTmpKey = Date.now()
      },
      $_emitter(event, data) {
        this.$emit(event, this.name, data)
      },
      handleInputChange(event) {
        let _this = this
        let file = event.target.files[0]
        if (!file) {
          return
        }
        if (event.target.files && event.target.files.length) {
          this.$_emitter('select', {
            file: file,
          })
        }
        console.log('##获取文件##')
        console.log('文件类型' + file.type)
        console.log('文件大小' + file.size)
        console.log('##获取文件##')

        let size = 1024 * 1024 * _this.size
        // // 检查文件类型
        // if (['jpeg', 'png', 'gif', 'jpg'].indexOf(file.type.split('/')[1]) < 0) {
        //   return Toast.info('文件类型仅支持 jpeg/png/gif')
        // }
        // 文件大小限制
        if (size != 0 && file.size > size) {
          _this.$_cleaeFile()
          return Toast.info('文件大小不能超过' + size + 'MB')
        }
        // 存储文件相关信息
        _this.imgFile.type = file.type || 'image/jpeg' // 部分安卓出现获取不到type的情况
        _this.imgFile.size = file.size
        _this.imgFile.name = file.name.lastIndexOf('.') == -1 ? file.name + '.jpg' : file.name
        _this.imgFile.lastModifiedDate = file.lastModifiedDate

        // 封装好的函数
        const reader = new FileReader()
        console.log('fileReader对象')
        // file转dataUrl是个异步函数，要将代码写在回调里
        reader.onload = function (e) {
          let result = e.target.result
          console.log('fileReader:onload')
          if (!_this.isCompress) {
            let blob = _this.dataURItoBlob(result)
            _this.$_emitter('complete', {
              blob: blob,
              dataUrl: result,
              file: new File([blob], _this.imgFile.name, {
                type: _this.imgFile.type
              })
            })
            _this.compressedDataUrl = result
            return _this.$_cleaeFile()
          }
          _this.compress(result).then(res => {
            _this.compressedDataUrl = res
            let blob = _this.dataURItoBlob(res)
            _this.$_emitter('complete', {
              blob: blob,
              dataUrl: res,
              file: new File([blob], _this.imgFile.name, {
                type: _this.imgFile.type
              })
            })
            _this.$_cleaeFile()
            // _this.processData(res)
          })
        }
        reader.readAsDataURL(file)
      },
      //压缩
      compress(dataURL) {
        let _this = this
        console.log('进去压缩方法')
        let img = new window.Image()
        img.src = dataURL
        return new Promise(resolve => {
          img.onload = function () {
            let scale = img.width / img.height
            let canvas = document.createElement('canvas')
            let ctx = canvas.getContext('2d')
            canvas.width = _this.outputWidth == -1 ? img.width : _this.outputWidth
            canvas.height = _this.outputWidth == -1 ? img.height : parseInt(_this.outputWidth / scale)
            ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
            let compressedDataUrl = canvas.toDataURL(_this.imgFile.type, _this.quality)
            console.log('#########压缩完成############')
            resolve(compressedDataUrl)
          }
        })
      },
      processData(dataUrl) {
        // 这里使用二进制方式处理dataUrl
        let _this = this
        console.log('processData')
        const binaryString = window.atob(dataUrl.split(',')[1])
        console.log('binaryString')
        const arrayBuffer = new ArrayBuffer(binaryString.length)
        console.log('arrayBuffer')
        console.log(arrayBuffer)
        const intArray = new Uint8Array(arrayBuffer)
        console.log('intArray')
        console.log(intArray)
        for (let i = 0, j = binaryString.length; i < j; i++) {
          intArray[i] = binaryString.charCodeAt(i)
        }
        const data = [intArray]
        let blob
        try {
          blob = new Blob(data, {
            type: _this.imgFile.type
          })
        } catch (error) {
          window.BlobBuilder = window.BlobBuilder ||
            window.WebKitBlobBuilder ||
            window.MozBlobBuilder ||
            window.MSBlobBuilder
          if (error.name === 'TypeError' && window.BlobBuilder) {
            const builder = new window.BlobBuilder()
            builder.append(arrayBuffer)
            blob = builder.getBlob(_this.imgFile.type)
          } else {
            Toast.info('版本过低，不支持上传图片')
            throw new Error('版本过低，不支持上传图片')
          }
        }

        // blob 转file
        const fileOfBlob = new File([blob], _this.imgFile.name)
        console.log('fileOfBlob')
        console.log(fileOfBlob)
        const formData = new FormData()
        _this.imgFile.size = fileOfBlob.size
        // type
        formData.append('type', _this.imgFile.type)
        // size
        formData.append('size', fileOfBlob.size)
        // name
        formData.append('name', _this.imgFile.name)
        // lastModifiedDate
        formData.append('lastModifiedDate', _this.imgFile.lastModifiedDate)
        // append 文件
        formData.append('file', fileOfBlob)
        console.log('formData')
        console.log(formData)
      },
      dataURItoBlob(dataURI) {
        // convert base64/URLEncoded data component to raw binary data held in a string
        let byteString

        /* istanbul ignore else */
        if (dataURI.split(',')[0].indexOf('base64') >= 0) {
          byteString = atob(dataURI.split(',')[1])
        } else {
          byteString = unescape(dataURI.split(',')[1])
        }

        // separate out the mime component
        const mimeString = dataURI
          .split(',')[0]
          .split(':')[1]
          .split(';')[0]

        // write the bytes of the string to a typed array
        const ia = new Uint8Array(byteString.length)

        for (let i = 0; i < byteString.length; i++) {
          ia[i] = byteString.charCodeAt(i)
        }

        return new Blob([ia.buffer], {
          type: mimeString
        })
      }
    }
  }
</script>
<style lang="less" scoped>
  .uploadImg {
    position: relative;
    width: 200px;
    height: 200px;
    line-height: 200px;
    text-align: center;
    border: 1px solid #dddddd;

    input[type='file'] {
      position: absolute;
      top: 0;
      left: 0;
      height: 100%;
      width: 100%;
      opacity: 0;
    }
  }
</style>